home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / RGASM.RAR / ASMCODE.EXE / CHAPT11 / SCRBLANK.ASM < prev    next >
Encoding:
Assembly Source File  |  1993-05-10  |  34.9 KB  |  644 lines

  1. ;
  2. ;       Program ScrBlank ( Chapter 11 )
  3. ;
  4.     page    55,132
  5. ;
  6. ;       This program installs additional handlers for following interrupts:
  7. ;       09h - keyboard
  8. ;       1Ch - timer
  9. ;       10h - video
  10. ;       33h - mouse
  11. ;       2Fh - multiplex handler
  12. ;
  13. ;       New function 193 (0C1h) is added to interrupt 2Fh 
  14. ;       This function has following subfunctions:
  15. ;       00 - installation check
  16. ;       01 - activates the driver
  17. ;       02 - deactivates the driver
  18. ;       03 - report the driver state; returns the state in AH (1 - on, 2 - off)
  19. ;       04 - switch border blinking On/Off
  20. ;       To call new function put its number into the AH register, 
  21. ;       the subfunction number into AL and call interrupt 1Ch
  22. ;
  23. NewFunc equ     0E0h
  24. TSRId   equ     193
  25. CheckIn equ     0                       ; subfunction "check installation"
  26. SwOn    equ     1                       ; subfunction "turn program on"
  27. SwOff   equ     2                       ; subfunction "turn program off"
  28. RepSt   equ     3                       ; subfunction "report status"
  29. RestPal equ     4
  30. BordSw  equ     5
  31. InAct   equ     0                       ; this value indicates "INACTIVE"
  32. Act     equ     13h                     ; this value indicate "ACTIVE"
  33. BlinkB  equ     1
  34. MaxTick equ     5460                    ; 5460 ticks = 5 minutes
  35.  
  36. _Text   segment para public 'CODE'
  37.     assume  cs:_Text,ds:nothing,es:nothing
  38. ;====================  Resident data =====================================
  39.     org     90h                     ;=== COM - variant
  40.     jmp     Start                   ;=== COM - Variant
  41. ActInd  db      Act                     ; activity indicator; if 0 - inactive
  42. NumTick dw      0                       ; number of timer ticks since last key
  43. NumTk1  dw      0
  44. BlankId db      0                       ; screen blank indicator; if 0 - not blankedA
  45. Blanked equ     13h                     ; signature "screen is blanked"
  46. BIOSSeg dw      40h                     ; segment address of BIOS data area
  47. ComSeg  dw      0                       ; segment addres of resident part (CS)
  48. IndStat db      0
  49. Within  equ     13                      ; sign of using INT 10 from ScrBlank
  50. ZerPal  db      16 dup (0), 0           ; zero value for palette registers
  51. CurPal  db      0,1,2,3,4,5,14h,7,38h,39h,3Ah,3Bh,3Ch,3Dh,3Eh,3Fh,0
  52. Border  db      0
  53. DefBord db      0
  54. BlinkId db      0
  55. PresEGA db      0
  56. ;===    save area for registers
  57. AX09    dw      0
  58. BX09    dw      0
  59. CX09    dw      0
  60. DX09    dw      0
  61. ES09    dw      0
  62. FLAG09  db      0
  63. AX1C    dw      0
  64. BX1C    dw      0
  65. CX1C    dw      0
  66. DX1C    dw      0
  67. ES1C    dw      0
  68. FLAG1C  db      0
  69.  
  70.     org     100h                    ;=== COM - Variant
  71. Addr100:jmp     start                   ;=== COM - Variant
  72. ;=====================  Resident code ====================================
  73.  
  74. RestScr proc    near
  75.     cmp     PresEGA,0               ; is EGA/VGA present?
  76.     jnz     REGAVGA                 ; if so, use EGA/VGA BIOS functions
  77. ;===    Restore screen for CGA/MDA/Hercules
  78.     mov     es,BIOSSeg              ; BIOS data accessable through ES       
  79.     mov     al,es:[65h]             ; get current content of mode register 
  80.     or      al,08h                  ; set bit "video enable"
  81.     mov     es:[65h],al             ; put changed content of mode register
  82.     mov     dx,3B8h                 ; address of video port - MDA/Hercules
  83.     out     dx,al                   ; set mode register to "beam on"
  84.     mov     dl,0D8h                 ; low part of address - CGA
  85.     out     dx,al                   ; set mode register to "beam on"
  86.     mov     IndStat,Within          ; set indicator "Within Scrblank"
  87.     mov     ax,0B00h                ; function 0Bh - Set Border/Palette
  88.     mov     bh,0                    ; subfunction 00h - Set Border Color
  89.     mov     bl,DefBord              ; BL - default border color
  90.     int     10h                     ; BIOS video service call
  91.     mov     IndStat,0               ; clear indicator "Within ScrBlank"     
  92.     jmp     ExRest                  ; exit from additional handler
  93. ;===    Restore screen for EGA/VGA
  94. REGAVGA:mov     ax,1002h                ; function "set all palette registers"
  95.     mov     es,ComSeg               ; ES points to current segment
  96.     mov     dx,offset CurPal        ; address of 17 defualt palette
  97.     mov     IndStat,Within          ; set indicator "Within Scrblank"
  98.     int     10h                     ; BIOS video service call
  99.     mov     IndStat,0               ; clear indicator "Within ScrBlank"     
  100. ExRest: ret                             ; exit from procedure
  101. RestScr endp
  102.  
  103. BlnkScr proc    near
  104. ;===    Blank the screen        
  105.     mov     BlankId,Blanked         ; set blank indicator
  106.     mov     NumTick,0               ; clear ticks counter
  107.     mov     Border,0                ; border will be black (first in chain)
  108.     mov     NumTk1,0                ; clear counter for border blinking
  109.     cmp     PresEGA,0               ; EGA/VGA adapter present?
  110.     jnz     BEGAVGA                 ; if so, process EGA/VGA
  111. ;---    Blank the screen for CGA/MDA/Hercules
  112.     mov     es,BIOSSeg              ; BIOS data accessable through ES 
  113.     mov     al,es:[65h]             ; get current content of mode register
  114.     and     al,not 08h              ; clear bit "video enable"
  115.     mov     es:[65h],al             ; put changed content of mode register
  116.     mov     dh,3                    ; high part of video port address
  117.     mov     dl,0B8h                 ; low part of address - MDA/HERCULES
  118.     out     dx,al                   ; set mode register to "beam off"
  119.     mov     dl,0D8h                 ; low part of address - CGA
  120.     out     dx,al                   ; set mode register to "beam off"
  121.     jmp     ExBln
  122. ;---    Blank the screen for EGA/VGA    
  123. BEGAVGA:mov     ax,1002h                ; function "set all palette registers"
  124.     mov     es,ComSeg               ; ES points to current segment
  125.     mov     dx,offset ZerPal        ; address of 17 zero values into ES:DX 
  126.     mov     IndStat,Within          ; set indicator "Within Scrblank"       
  127.     int     10h                     ; BIOS video service call
  128.     mov     IndStat,0               ; clear indicator "Within ScrBlank"     
  129. ExBln:  ret
  130. BlnkScr endp
  131.  
  132. BliBord proc    near
  133. ;===    is it time to change the border color?
  134.     inc     NumTk1                  ; number of ticks before changing border
  135.     cmp     NumTk1,91               ; have 5 seconds gone?
  136.     jl      ExBord                  ; if not, exit from handler
  137. ;===    test whether blinking border is requested
  138.     cmp     BlinkId,BlinkB          ; blinking requested
  139.     jne     ExBord                  ; if not, exit from handler
  140. ;===    prepare the new color value     
  141.     mov     NumTk1,0                ; clear counter of ticks for border
  142.     inc     Border                  ; next color of border
  143.     and     Border,03h              ; only colors 0-3 valid (CGA compatible)
  144. ;===    set the new border color 
  145.     mov     ax,0B00h                ; function 0Bh - "Set Palette/Border"           
  146.     mov     bh,0                    ; subfunction 00h - Set Border Color
  147.     mov     bl,Border               ; BL - border color     
  148.     mov     IndStat,Within          ; set indicator "Within Scrblank"
  149.     cmp     PresEga,0               ; EGA/VGA present?      
  150.     jnz     BliEGA
  151.     int     10h                     ; BIOS video service call
  152.     jmp     ClStat
  153. ;===    make border blinking on EGA/VGA 
  154. BliEGA: xchg    bh,bl                   ; Border Color into BH, zero into BL 
  155.     mov     ah,10h                  ; function 10h - Get/Set Palette
  156.     mov     al,01h                  ; subfunction 01h - Set Border Color
  157.     int     10h                     ; BIOS video service call
  158. ClStat: mov     IndStat,0               ; clear indicator "Within ScrBlank"     
  159. ExBord: ret                             ; exit from procedure
  160. BliBord endp    
  161.  
  162. NewMous proc    near
  163. ;===    save AX and flags
  164.     mov     AX33,ax                 ; save original value of AX register 
  165.     lahf                            ; original flags into AH register
  166.     mov     Flag33,ah               ; save original flags
  167.     mov     ax,AX33                 ; restore original value of AX register 
  168. ;===    check function of mouse handler 
  169.     cmp     al,0Bh                  ; read motion counters?
  170.     je      CallMou                 ; if so, call original handler
  171.     cmp     al,04h                  ; position cursor?
  172.     je      CallMou                 ; if so, call original handler  
  173.     cmp     al,03h                  ; read mouse state?
  174.     jne     ToOldM                  ; if not, to old handler
  175. ;===    call original handler   
  176. CallMou:pushf
  177.     call    dword ptr StdMous       ; call standard handler
  178. ;===    check whether buttons state and mouse location changed since last call  
  179.     mov     ax,AX33                 ; restore original value of AX register         
  180. TstBX:  cmp     bx,PrevBX               ; buttons state changed?
  181.     jne     RestS                   ; to saving current position and state
  182. TstCX:  cmp     cx,PrevCX               ; X coordinate changed?
  183.     jne     RestS                   ; to saving current position and state
  184. TstDX:  cmp     dx,PrevDX               ; Y coordinate changed?
  185.     jne     RestS                   ; to saving current position and state
  186.     jmp     ToOldM                  ; to original mouse handler
  187. ;===    restore AX and flags and exit from the handler  
  188. Exit33: mov     ah,FLAG09               ; original flags int AH register
  189.     sahf                            ; restore original flags
  190.     mov     ax,AX33                 ; restore original value of AX register
  191.     mov     NumTick,0               ; mouse active - clear ticks counter    
  192.     iret                            ; exit from handler
  193. ;===    save buttons state and mouse location for next use      
  194. RestS:  mov     PrevBX,bx               ; save current buttons state
  195.     mov     PrevCX,cx               ; save current X coordinate
  196.     mov     PrevDX,dx               ; save current Y coordinate
  197. ;===    check   if screen is blanked and restore it if mouse is active
  198. ProcM:  cmp     BlankId,Blanked         ; is screen blanked?
  199.     jne     Exit33                  ; if not - nothing to do
  200.     mov     BlankId,0               ; clear blank indicator 
  201.     mov     NumTick,0               ; mouse active - clear ticks counter
  202. ;---    save register used      
  203.     mov     BX33,bx                 ; save original value of BX register 
  204.     mov     CX33,cx                 ; save original value of CX register 
  205.     mov     DX33,dx                 ; save original value of DX register 
  206.     mov     ES33,es                 ; save original value of ES register 
  207.     call    RestScr 
  208. ;---    restore registers               
  209.     mov     es,ES33                 ; restore original value of ES register 
  210.     mov     dx,DX33                 ; restore original value of DX register 
  211.     mov     cx,CX33                 ; restore original value of CX register 
  212.     mov     bx,BX33                 ; restore original value of BX register 
  213.     jmp     Exit33
  214. ;===    pass the control to the standard handler of the interrupt 33h   
  215. ToOldM: mov     ah,FLAG09               ; original flags int AH register
  216.     sahf                            ; restore original flags
  217.     mov     ax,AX33                 ; restore original value of AX register 
  218.     jmp     dword ptr StdMous
  219. StdMous dw      ?,?
  220. OldOffM equ     StdMous[0]              ; here will be ofsset
  221. OldSegM equ     StdMous[2]              ; here will be segment
  222. Flag33  db      ?
  223. AX33    dw      ?
  224. BX33    dw      ?
  225. CX33    dw      ?
  226. DX33    dw      ?
  227. ES33    dw      ?
  228. PrevBX  dw      0
  229. PrevCX  dw      0
  230. PrevDX  dw      0
  231. NewMous endp
  232.  
  233. NewInt9 proc    near                    ; additional handler for interrupt 09h
  234.     mov     AX09,ax                 ; save original value of AX register 
  235.     lahf                            ; original flags into AH register
  236.     mov     FLAG09,ah               ; save original flags
  237.     mov     NumTick,0               ; key pressed - clear ticks counter
  238.     cmp     BlankId,Blanked         ; is screen blanked?
  239.     jne     ToOld9                  ; if not - nothing to do
  240.     mov     BlankId,0               ; clear blank indicator
  241. ;===    Save register used      
  242.     mov     BX09,bx                 ; save original value of BX register 
  243.     mov     CX09,cx                 ; save original value of CX register 
  244.     mov     DX09,dx                 ; save original value of DX register 
  245.     mov     ES09,es                 ; save original value of ES register 
  246.     call    RestScr 
  247. ;===    Read a key from keyboard and ignore this keystroke
  248. GetKey: in      al,60h                  ; read key code
  249.     in      al,61h                  ; read port B of PIC
  250.     or      al,80h                  ; set bit 7 to 1
  251.     out     61h,al                  ; send this value inti port B
  252.     jmp     $+2                     ; wait for some time on fast PCs
  253.     and     al,not 80h              ; clear bit 7 
  254.     out     61h,al                  ; send into port B
  255.     mov     al,20h                  ; signal "end of interrupt processing" 
  256.     out     20h,al                  ; send to Interrupt Controller
  257. ;===    restore registers               
  258.     mov     ah,FLAG09               ; original flags int AH register
  259.     sahf                            ; restore original flags
  260.     mov     es,ES09                 ; restore original value of ES register 
  261.     mov     dx,DX09                 ; restore original value of DX register 
  262.     mov     cx,CX09                 ; restore original value of CX register 
  263.     mov     bx,BX09                 ; restore original value of BX register 
  264.     mov     ax,AX09                 ; restore original value of AX register 
  265.     iret
  266. ;===    Pass the control to the standard handler of the interrupt 09h   
  267. ToOld9: mov     ah,FLAG09               ; original flags int AH register
  268.     sahf                            ; restore original flags
  269.     mov     ax,AX09                 ; restore original value of AX register         
  270.     db      0EAh                    ; this is code for JMP FAR
  271. OldOff9 dw      0                       ; here will be ofsset
  272. OldSeg9 dw      0                       ; here will be segment
  273. NewInt9 endp
  274.  
  275. NewInt10        proc
  276.     pushf                           ; push original flag onto stack
  277.     cmp     IndStat,Within          ; INT 10 requested from ScrBlank?
  278.     je      ToOld10                 ; if so, go to standard handler
  279.     cmp     ah,10h                  ; palette/border servicing?
  280.     jne     ToOld10                 ; if not, to old handler
  281.     cmp     al,00h                  ; Set Palette Register function?
  282.     jne     Not00h                  ; if not - check other function
  283.     mov     al,bh                   ; save original color value
  284.     mov     bh,0                    ; BX contains number of register
  285.     mov     CurPal[bx],al           ; change color value in paleete 
  286.     mov     bh,al                   ; restore original color value
  287.     mov     al,0                    ; restore value 00 for AL register
  288.     jmp     ToOld10                 ; to original handler of INT 10h
  289. Not00h: cmp     al,01h                  ; Set Border Color function?
  290.     jne     Not01h                  ; if not - check for other function
  291.     mov     CurPal[16],bh           ; save changed border color
  292.     jmp     ToOld10                 ; if not, to old handler
  293. Not01h: cmp     al,02h                  ; Set Entire Palette Function
  294.     jne     Not02h                  ; if not - check other function
  295.     mov     CX10,cx                 ; save CX register
  296.     mov     cx,17                   ; CX will be cycle counter
  297.     mov     BX10,bx                 ; save BX register
  298.     mov     bx,0                    ; BX - number of source register
  299.     mov     DI10,di                 ; save DI register
  300.     mov     di,dx                   ; offset of new pallete (ES:DX) into DX
  301. CopyPal:mov     al,es:[di]              ; copy one paleete register into AL
  302.     mov     CurPal[bx],al           ; save it for screen restoring 
  303.     inc     bx                      ; advance target (palette for restoring)
  304.     inc     di                      ; advance source (palette to be set now)
  305.     loop    CopyPal                 ; next step (17 times)
  306.     mov     cx,CX10                 ; restore CX
  307.     mov     bx,BX10                 ; restore CX
  308.     mov     di,DI10                 ; restore DI
  309.     mov     al,02h                  ; restore AL
  310.     jmp     ToOld10                 ; to old handler        
  311. Not02h: cmp     ah,0Bh                  ; Set Palette/Border function (CGA)?
  312.     jne     Not0Bh                  ; if not - check other function
  313.     cmp     bh,0                    ; Set Border Color subfunction?
  314.     jne     Not0Bh                  ; if not, check for other functions
  315.     mov     CurPal[16],bl           ; save changed border color (EGA/VGA)
  316.     mov     DefBord,bl              ; save changed border color (CGA)
  317.     jmp     ToOld10                 ; to old handler
  318. Not0Bh: 
  319. ToOld10:popf
  320.     db      0EAh                    ; this is code for JMP FAR
  321. OldO10  dw      0                       ; here will be ofsset
  322. OldS10  dw      0                       ; here will be segment
  323. BX10    dw      ?
  324. CX10    dw      ?
  325. DI10    dw      ?
  326. NewInt10        endp
  327. ;===
  328. Handler proc    near                    ; additional handler for interrupt 1Ch
  329.     mov     AX1C,ax                 ; save original value of AX register 
  330.     lahf                            ; original flags into AH register       
  331.     mov     FLAG1C,ah               ; save original flags
  332.     mov     ax,AX1C                 ; restore original value of AX register
  333.     cmp     ActInd,Act              ; is activity indicator set?
  334.     jne     ToOld1C                 ; if not, pass control to old handler
  335. ;===    Check whether the screen is already blanked
  336. Process:mov     BX1C,bx                 ; save original value of BX register 
  337.     mov     CX1C,cx                 ; save original value of CX register 
  338.     mov     DX1C,dx                 ; save original value of DX register 
  339.     mov     ES1C,es                 ; save original value of ES register 
  340.     cmp     BlankId,Blanked         ; is screen blanked?
  341.     jne     ChkTime                 ; if not, check whether time has gone
  342.     call    BliBord                 ; show blinking border
  343.     jmp     Rest1C
  344. ;===    Has the time gone?
  345. ChkTime:inc     NumTick                 ; increase ticks counter
  346.     cmp     NumTick,MaxTick         ; is it time to blank screen
  347.     jl      Rest1C                  ; if not, procced to standard handler
  348.     call    BlnkScr
  349. ;===    Restore registers       
  350. Rest1C: mov     es,ES1C                 ; restore original value of ES register 
  351.     mov     dx,DX1C                 ; restore original value of DX register
  352.     mov     cx,CX1C                 ; restore original value of CX register
  353.     mov     bx,BX1C                 ; restore original value of BX register
  354. ;===    Pass the control to the standard handler of the interrupt 1Ch   
  355. ToOld1C:mov     ah,FLAG1C               ; original flags into AH register
  356.     sahf                            ; restore original flags
  357.     mov     ax,AX1C                 ; restore original value of AX register
  358.     db      0EAh                    ; this is code for JMP FAR
  359. OldOffC dw      0                       ; here will be ofsset
  360. OldSegC dw      0                       ; here will be segment
  361. Handler endp
  362.  
  363. MulHand proc    near                    ; NEW MULTIPLEX HANDLER
  364.     pushf                           ; push original flags
  365.     cmp     ah,TSRId                ; is user function specified?
  366.     jne     ToOld2F                 ; if not - to old handler
  367.     cmp     bx,AddSign              ; does BX contain additional signature
  368.     jne     ToOld2F                 ; if not - caller isn't ScrBlank
  369.     cmp     al,CheckIn              ; Installation Check?
  370.     jne     Other1                  ; if not - check for other function
  371.     mov     al,0FFh                 ; standard convention for Presence
  372.     mov     bx,PresSign             ; presence signature into BX
  373. Other1: cmp     al,SwOn                 ; function "Switch ON?"
  374.     jne     Other2                  ; if not, continue testing
  375.     mov     ActInd,Act              ; set indicator to ACTIVE (ON)
  376.     jmp     Exit2F                  ; to exit from handler
  377. Other2: cmp     al,SwOff                ; function "Switch OFF"?
  378.     jne     Other3                  ; if not, continue testing      
  379.     mov     ActInd,InAct            ; set indicator to INACTIVE (OFF)
  380.     jmp     Exit2F                  ; to exit from handler
  381. Other3: cmp     al,RepSt                ; function "Report state"?
  382.     jne     Other4                  ; if not, continue testing      
  383.     mov     ah,ActInd               ; set indicator to INACTIVE (OFF)
  384.     jmp     Exit2F                  ; to exit from handler
  385. Other4: cmp     al,BordSw               ; function "Toggle Border Blinking"
  386.     jne     Other5                  ; if not, continue testing      
  387.     xor     BlinkId,BlinkB          ; toggle blinking indicator
  388.     mov     ah,BlinkId              ; return new blinking state
  389.     jmp     Exit2F                  ; to exit from handler
  390. Other5: 
  391. Exit2F: popf
  392.     iret
  393. ToOld2F:popf
  394. JMPto2F:jmp     dword ptr Old2Fh
  395. Old2Fh  dw      ?,?
  396. OldmulO equ     Old2Fh[+0]
  397. OldMulS equ     Old2Fh[+2]
  398. MulHand endp
  399.  
  400. AddSign dw      1951
  401. PresSign dw     7654    
  402. ;===    Installation part of the program
  403. BegInst label   byte                    ; This is start of installation part
  404. ParmInd db      0
  405. PspAddr dw      ?
  406. RetCode db      0
  407. InvPCod equ     16
  408. HelpCod equ     5
  409. DefPal  db      0,1,2,3,4,5,14h,7,38h,39h,3Ah,3Bh,3Ch,3Dh,3Eh,3Fh,0
  410. ;===    Set segment register
  411. Start:  mov     ah,51h                  ; get PSP address (undocumented)
  412.     int     21h                     ; DOS service call
  413.     mov     PspAddr,bx              ; save segment address of PSP
  414.     mov     ComSeg,cs               ; save address of command segment
  415.     mov     sp,0F000h               ; set stack to command segment's top
  416.     mov     es,PspAddr              ; ES points to PSP
  417.     mov     ds,ComSeg               ; DS = CS - data and code are the same 
  418. ;===    Check whether the program is already installed
  419.     mov     ah,TSRId                ; user subfunction of multiplex handler
  420.     mov     al,CheckIn              ; AL - installation check
  421.     mov     bx,AddSign              ; BX - additional signature
  422.     int     2Fh                     ; multiplex handler call
  423.     cmp     al,0FFh                 ; common convention satisfied:
  424.     jne     InsSta                  ; if not - start installation
  425.     cmp     bx,PresSign             ; does BX contain presence signature?
  426.     jne     InsSta                  ; if not - start installation
  427.     jmp     Already                 ; otherwise program is already installed
  428. ;===    The process of installation starts here 
  429. ;===    Free the environment memory block
  430. InsSta: mov     es,es:[2Ch]             ; address of environment block into ES 
  431.     mov     ah,49h                  ; function 49h - free memory block
  432.     int     21h                     ; DOS service call
  433. ;===    Test whether EGA/VGA are present        
  434.     mov     PresEGA,10h
  435.     mov     bl,10h                  ; 10h - get EGA/VGA configuration 
  436.     mov     ah,12h                  ; function 12h - get/set information
  437.     int     10h                     ; BIOS video service call
  438.     xor     PresEGA,bl              ; if EGA/VGA present PresEGA <> 0
  439. ;===    set internal variables for resident part
  440.     mov     es,PspAddr              ; ES points to start of PSP
  441.     mov     ActInd,Act              ; program is ON immediately after start
  442.     mov     NumTick,0               ; clear counter for screen blanking
  443.     mov     NumTk1,0                ; clear counter for border colors play
  444.     mov     BlankId,0               ; screen isn't blanked
  445.     mov     IndStat,0               ; INT 10h isn't called from within TSR 
  446.     mov     BlinkId,BlinkB          ; border blinking is ON
  447.     mov     Border,0                ; initial border is black
  448.     mov     DefBord,0               ; default border is black
  449.     mov     cx,17                   ; CX will be cycle counter
  450.     mov     bx,0                    ; BX will be index
  451. AssPal: mov     al,DefPal[bx]           ; read one value for palette register
  452.     mov     ZerPal[bx],0            ; clear one register of default palette
  453.     mov     CurPal[bx],al           ; load one register for current palette 
  454.     inc     bx                      ; advance index to process next value
  455.     loop    AssPal                  ; next step (17 times)
  456.     
  457. ;===    Output initial message  
  458. Install:mov     ah,09                   ; function 09 - text string output
  459.     lea     dx,BegMsg               ; DX - address of message
  460.     int     21h                     ; DOS service call
  461. ;===    Install handler for multiplex interrupt 2Fh
  462.     mov     ax,352Fh                ; get interrupt vector 2Fh
  463.     int     21h                     ; DOS service call
  464.     mov     OldMulO,bx              ; save offsett of old handler for 1Ch
  465.     mov     OldMulS,es              ; save segment of old handler for 1Ch
  466.     mov     dx,offset MulHand       ; offset of new Multiplex Handler
  467.     mov     ah,25h                  ; function 25h - set interrupt vector
  468.     int     21h                     ; DOS service call
  469. ;===    Install handler for BIOS interrupt 09h (keyboard)
  470.     mov     ax,3509h                ; get interrupt vector 09h
  471.     int     21h                     ; DOS service call
  472.     mov     cs:OldOff9,bx           ; save offsett of old handler for 09h
  473.     mov     cs:OldSeg9,es           ; save segment of old handler for 09h
  474.     mov     ah,25h                  ; function 25h - set interrupt vector
  475.     mov     dx,offset NewInt9       ; address of new INT 09 handler
  476.     int     21h                     ; DOS service call
  477. ;===    Install handler for BIOS interrupt 1Ch (timer)  
  478.     mov     ax,351Ch                ; get interrupt vector 1Ch
  479.     int     21h                     ; DOS service call
  480.     mov     cs:OldOffC,bx           ; save offsett of old handler for 1Ch
  481.     mov     cs:OldSegC,es           ; save segment of old handler for 1Ch
  482.     mov     ah,25h                  ; function 25h - set interrupt vector   
  483.     mov     dx,offset Handler       ; address of handler
  484.     int     21h                     ; DOS service call
  485. ;===    Install handler for BIOS interrupt 10h (video)  
  486.     mov     ax,3510h                ; get interrupt vector 10h
  487.     int     21h                     ; DOS service call
  488.     mov     cs:OldO10,bx            ; save offsett of old handler for 10h
  489.     mov     cs:OldS10,es            ; save segment of old handler for 10h
  490.     mov     ah,25h                  ; function 25h - set interrupt vector   
  491.     mov     dx,offset NewInt10      ; address of new INT 09 handler
  492.     int     21h                     ; DOS service call
  493. ;===    Install handler for interrupt 33h (mouse)       
  494.     mov     ax,3533h                ; get interrupt vector 33h
  495.     int     21h                     ; DOS service call
  496.     mov     cs:OldOffM,bx           ; save offsett of old handler for 33h
  497.     mov     cs:OldSegM,es           ; save segment of old handler for 33h
  498.     mov     ah,25h                  ; function 25h - set interrupt vector   
  499.     mov     dx,offset NewMous       ; address of new INT 33 handler
  500.     int     21h                     ; DOS service call
  501. ;===    output the message "program is installed"
  502.     lea     dx,Loaded               ; DX - address of message
  503.     mov     ah,09h                  ; function 09 - output string
  504.     int     21h                     ; DOS service call
  505. ;===    Calculate the size of the resident part and exit the program    
  506.     lea     dx,BegInst      
  507.     add     dx,110h                 ; PSP length plus 16 byte (insurance) 
  508.     mov     cx,4                    ; set counter for shift
  509.     shr     dx,cl                   ; 4 bits to the right - divide by 16
  510.     mov     ax,3100h                ; 31h - terminate and state resident
  511.     int     21h                     ; DOS service call
  512. ;===    Process situation "Resident part is already installed"
  513. Already:
  514. ;===    Check whether parameters are present    
  515.     mov     es,PspAddr              ; addres of PSP into ES
  516.     cmp     byte ptr es:[80h],1     ; are there parameters? 
  517.     jle     NoParm                  ; if not, skip parameters processing
  518. ;===    Skip separators "/", "-"  and blanks    
  519.     mov     bx,80h                  ; BX - beginning of parameter string
  520. TestSep:inc     bx                      ; BX points to next character 
  521.     cmp     bl,byte ptr es:[80h]    ; end of parameter string?
  522.     jge     NoParm                  ; if so - parameters not found  
  523.     cmp     byte ptr es:[bx],'/'    ; is current character separator? 
  524.     je      TestSep                 ; if so - try next character
  525.     cmp     byte ptr es:[bx],'-'    ; is current character separator? 
  526.     je      TestSep                 ; if so - try next character
  527.     cmp     byte ptr es:[bx],' '    ; is current character blank?
  528.     je      Testsep                 ; if so - try next character
  529. ;===    Separator found - process parameter string
  530. FndSep: cmp     byte ptr es:[bx],'?'    ; question mark specified?
  531.     je      Help                    ; if so, process "HELP"
  532.     and     byte ptr es:[bx],0DFh   ; force first letter uppercase
  533.     cmp     byte ptr es:[bx],'H'    ; is first letter 'H'?
  534.     je      Help                    ; if so, process "HELP" 
  535.     cmp     byte ptr es:[bx],'R'    ; is first letter 'R'?
  536.     je      PalRest                 ; if so, process "Restore Palette" 
  537.     cmp     byte ptr es:[bx],'B'    ; is first letter 'B'?
  538.     je      SwBord                  ; if so, process "Switch Border Blink"
  539.     cmp     byte ptr es:[bx],'O'    ; is first letter 'O'?
  540.     jne     InvParm                 ; if not - missing or invalid parameter
  541.     and     byte ptr es:[bx+1],0DFh ; force second letter uppercase
  542.     cmp     byte ptr es:[bx+1],'N'  ; is second letter 'N'?
  543.     je      FuncOn                  ; if so, process "ON"
  544.     cmp     byte ptr es:[bx+1],'F'  ; is second letter 'F'?
  545.     jne     InvParm                 ; if not - invalid parameter
  546.     and     byte ptr es:[bx+2],0DFh ; force third letter uppercase
  547.     cmp     byte ptr es:[bx+2],'F'  ; is third letter 'F'?
  548.     jne     InvParm                 ; if not, process "INVALID PARMS"
  549. ;===    Function "Switch OFF"   
  550. FuncOff:mov     al,SwOff                ; code for function "OFF" into AL
  551.     lea     dx,MakeOff              ; DS:DX - addres of message "Turned OFF"
  552.     mov     RetCode,SwOff           ; return code "SWITCHED OFF"
  553.     jmp     CallMul                 ; to switch program state
  554. ;===    Function "Switch ON"
  555. FuncOn: mov     al,SwOn                 ; subfunction "Turn ON"
  556.     mov     RetCode,SwON            ; return code "SWITCHED ON"
  557.     lea     dx,MakeOn               ; DS:DX - addres of message "Turned ON"
  558. ;===    Call multiplex handler (function code in AL)
  559. CallMul:mov     ah,TSRId                ; AH - TSR's identifier
  560.     mov     bx,AddSign              ; BX - additional signature
  561.     int     2Fh                     ; call multiplex handler
  562. ;===    Print a message (address in DS:DX)      
  563. PrnMsg: mov     ah,09h                  ; function 09 - output text string
  564.     int     21h                     ; DOS service call
  565. ;===    Exit from program (return code in RetCode)      
  566. ExitPrg:mov     ah,4Ch                  ; function 4Ch - terminate process
  567.     mov     al,RetCode              ; al - return code (ErrorLevel)
  568.     int     21h                     ; DOS service call
  569. ;===    Function :Switch Border Blinking"
  570. SwBord: mov     al,BordSw               ; AL - subfunction "Toggle Blinking"
  571.     mov     ah,TSRId                ; AH - TSR's identifier
  572.     mov     bx,AddSign              ; BX - additional signature
  573.     mov     dx,' N'                 ; set tail of message to "N "
  574.     int     2Fh                     ; call multiplex handler        
  575.     cmp     ah,BlinkB               ; is border blinking?
  576.     je      BordDon                 ; if so, output correspondent message
  577.     mov     dx,'FF'                 ; set tail of message to "FF"
  578. BordDon:mov     OnOff,dx                ; form either "ON" or "OFF" 
  579.     mov     RetCode,BordSw          ; return code
  580.     lea     dx,TogBor               ; address of message "Toggled"
  581.     jmp     PrnMsg                  ; to print message and finish program   
  582.     
  583. ;===    Process the situation "no parameter"    
  584. NoParm: mov     al,RepSt                ; AL - subfunction "Report Status"
  585.     mov     ah,TSRId                ; AH - function of INT 2Fh (identifier)
  586.     mov     bx,AddSign              ; BX - additional signature     
  587.     int     2Fh                     ; multiplex handler call
  588.     lea     dx,MakeOff              ; DS:DX - addres of message "Turned OFF"
  589.     mov     RetCode,SwOff           ; return code "SWITCHED OFF"
  590.     cmp     ah,Act                  ; is code "Turned ON" returned? 
  591.     jne     PrnMsg                  ; if not, exit; "OFF" will be output
  592.     lea     dx,MakeOn               ; DS:DX - addres of message "Turned ON"
  593.     mov     RetCode,SwOn            ; return code "SWITCHED ON"
  594.     jmp     PrnMsg                  ; to print message and exit
  595. ;===    Restore Palette
  596. Palrest:mov     ax,1002h                ; function "set all palette registers"
  597.     mov     es,ComSeg               ; ES points to current segment
  598.     mov     dx,offset DefPal        ; address of 17 defualt palette
  599.     int     10h                     ; BIOS video service call
  600.     lea     dx,PalMsg               ; DS:DX - address of message "Palette.."
  601.     jmp     PrnMsg                  ; to print message and exit     
  602. ;===    Output help message     
  603. Help:   lea     dx,BegMsg               ; DS:DX - address of initial message
  604.     mov     RetCode,HelpCod         ; return code "HELP message output"     
  605. Help2:  mov     ah,09h                  ; function 09 - output text string
  606.     int     21h                     ; DOS service call
  607.     lea     dx,ParmTxt              ; DS:DX - address of HELP message
  608.     jmp     PrnMsg                  ; to print message and exit
  609. ;===    Process the situation "INVALID PARAMETERS"
  610. InvParm:lea     dx,Invalid              ; DS:DX addres of message "Invalid"
  611.     mov     RetCode,InvPCod         ; return code "Invalid Parameters"
  612.     jmp     Help2                   ; to print message and exit
  613. ;===    Data for non-resident part of the program
  614. CR      equ     0Ah
  615. LF      equ     0Dh
  616. EndMsg  equ     24h 
  617. Invalid db      CR,LF,'Can not interprete parameters specified.'
  618.     db      CR,LF,'The valid form of command line is:',CR,LF,EndMsg
  619. PalMsg  db      CR,LF,'The default palette has been restored',CR,LF,EndMsg      
  620. BegMsg  db      CR,LF,'The resident screen blanker     version 4.2     19.11.92'
  621.     db      CR,LF,'Copyright (C) 1992 V.B.Maljugin,     Russia,    Voronezh'
  622.     db   CR,CR,LF,'Puts out the screen when the keyboard is  5 minutes idle'        
  623.     db      CR,LF,'The MDA/CGA/Hercules/EGA/MCGA/VGA adapters are supported'
  624. CrLf    db      CR,LF,EndMsg
  625. Loaded  db      CR,LF,'The screen blanker is installed successfully',CR,LF,EndMsg
  626. MakeOn  db      CR,LF,'The screen blanker is now ACTIVE',CR,LF,EndMsg
  627. MakeOff db      CR,LF,'The Screen blanker is now INACTIVE',CR,LF,EndMsg
  628. TogBor  db      CR,LF,'The border blinking from now will be O'
  629. OnOff   dw      2020h
  630.     db      EndMsg    
  631. HelpTxt db      CR,LF,CR,LF, 'Call: '
  632. ParmTxt db      CR,LF,'ScrBlank [on | off | b | r | /? | /h | -? | -h] ',CR,LF
  633.     db      CR,LF,'Parameters:                                           '
  634.     db      CR,LF,'on  - make the screen blanker active                  '
  635.     db      CR,LF,'off - make the screen blanker inactive                '
  636.     db      CR,LF,'b   - toggle the border blinking                      '
  637.     db      CR,LF,'r   - restore the default palette                     '
  638.     db      CR,LF,'rest of list - output this text',CR,LF
  639.     db      CR,LF,'Call this program without parameters to determine its '
  640.     db            'current state.', CR,LF,EndMsg
  641. _text   ends
  642.     end     Addr100                 ; COM variant
  643. ;       end     Start
  644.